


package model.delayed.logistical;

import java.util.ArrayList;
import java.util.Collection;

import model.delayed.Account;
import model.delayed.Event;
import model.delayed.Loan;
import model.delayed.LongtermReturnInvestment;
import model.delayed.ModelController;
import model.delayed.ShortTermReturnInvestment;
import model.delayed.savings;



/**
 * A logistical controller which has takes care of investments and debt accounts
 * Always negative
 * @author Naren Meadem
 * @version Dec 1, 2012
 */




public class LogisticalController implements ModelController
{

	
	//I will take care of the Investments and debts 
	
	
	//inputs needed Expenses + data from investments, loans + current time 
	
	
	// Idea is to remove EMI of investments and loan from the big account 
	
	// Add money to ROI of the investments for the specified time period cycle
	
	//If the EMI cycle is done for investments then we should add investments expected value to asset value 
	
	// if we want to pull the money from that then it will be having a delay 
	
	//ROI on the investments will be always available
	
	
	// loan amount if paid will be deactivated
	
	public Loan my_loan;
	public LongtermReturnInvestment my_longterm;
	public ShortTermReturnInvestment my_shortterm;
	public savings my_saving;
	public Account my_checking;
	
	
public LogisticalController (final Loan the_loan, final LongtermReturnInvestment the_longterm, final ShortTermReturnInvestment the_shortterm, final savings the_saving, final Account the_checking) 
	
	{
	my_loan = the_loan;
	my_longterm = the_longterm;
	my_shortterm = the_shortterm;	
	my_saving = the_saving;	
	my_checking = the_checking;
	}
	
@Override public Collection<Event> compute(final long the_time,
		final Collection<Event> the_events)
		{
	
	Collection<Event> the_events_investments= new ArrayList<Event>();
	// check the amount we should deduct from each account
	
	//if loan is valid we take money away from checking account and to keep track we remove pending amount form loan account
	if(my_loan.getValue() < 0)
	    if (the_time%my_loan.getTimeperiod() == 0) {
	    	the_events.add(my_checking.withdraw(-my_loan.getEMI(), the_time)); 
	    	the_events_investments.add(my_loan.deposit(my_loan.getEMI(), the_time));}
	
	//if Longterm investments account is valid then we caluclate the following
	
	if (my_longterm.getValue() < 0)
	{
		//if EMI is still present
		if (the_time%my_longterm.EMI_time() ==0 ) {
			the_events.add(my_checking.withdraw(-my_longterm.EMI(), the_time)); 
			the_events_investments.add(my_longterm.deposit(my_longterm.EMI(), the_time));
			
			//need to have some special field for asset value which i did keep
			if ((my_longterm.getValue() + my_longterm.EMI() >=0)  ) {
				//the_events.add(my_saving.deposit(my_longterm.getLongTermValue(), the_time+30));
				my_saving.add_AssetValue(my_longterm.getLongTermValue());
				my_longterm.changeValue( -(my_longterm.getValue() + my_longterm.EMI()));
			
			}
		
		}
		
	}
	if (my_longterm.getValue() < 0 || my_saving.get_AssetValue() > 0)
	{
	
		// if this investment has ROI
		
		if (the_time%my_longterm.ReturnOnInvestmentCycle() == 0) {
			the_events.add(my_checking.deposit(my_longterm.ReturnOnInvestmet(), the_time));}
			
		

		
	}
	
	
	if (my_shortterm.getValue() < 0)
	{
		//if EMI is still present
		if (the_time%my_shortterm.EMI_time() ==0 ) {
			the_events.add(my_checking.withdraw(-my_shortterm.EMI(), the_time));
			the_events_investments.add(my_shortterm.deposit(my_shortterm.EMI(), the_time));
			
			
			//need to have some special field for asset value which i did keep
			if (my_shortterm.getValue() + my_shortterm.EMI() >= 0) {
				//the_events.add(my_saving.deposit(my_shortterm.getLongTermValue(), the_time+30));
			
		     my_saving.add_AssetValue(my_shortterm.getLongTermValue());
			
		     my_shortterm.changeValue( -(my_shortterm.getValue() + my_shortterm.EMI()));
			}	
		
		}
		
	}
	
	if (my_shortterm.getValue() < 0 || my_saving.get_AssetValue() > 0)
	{
	
		// if this investment has ROI
		
		if (the_time%my_shortterm.ReturnOnInvestmentCycle() == 0) {
			the_events.add(my_checking.deposit(my_shortterm.ReturnOnInvestmet(), the_time));}
			
		
	
		
	}

	
	long net = totalTo(the_events);
	if (net < 0)
	{
		
		if (my_saving.getValue() + net < 0)
		{
			
		
				
				//first check the assets we have in savings account
				
				if (my_saving.get_AssetValue()>=-(my_saving.getValue() + net)) { 
					
					my_saving.set_AssetValue(my_saving.get_AssetValue() + (my_saving.getValue() + net));
					
					the_events.add(my_saving.deposit((-(my_saving.getValue() + net)), the_time+my_saving.delay_in_return()));
					
				}
				
				else if(my_shortterm.getaccumulatedValue()>= -(my_saving.getValue() + net)) {
					the_events_investments.add(my_shortterm.withdraw(-(-(my_saving.getValue() + net)), the_time));
					
					the_events.add(my_saving.deposit(( -(my_saving.getValue() + net)), the_time+my_shortterm.delay_in_return()));
					}
				
				else if(my_longterm.getaccumulatedValue()>= - (my_saving.getValue() + net) ) {
					the_events_investments.add(my_longterm.withdraw(-(- (my_saving.getValue() + net)), the_time));
					
					the_events.add(my_saving.deposit((- (my_saving.getValue() + net)), the_time+my_longterm.delay_in_return()));
					}
				
		}
		else {
		the_events.add(my_saving.withdraw(net, the_time));
		the_events.add(my_checking.deposit(-net, the_time));
		}
		
		}
		
	 else if (net > 0)
	{
		
		the_events.add(my_saving.deposit(net, the_time));
		the_events.add(my_checking.withdraw(-net, the_time));
	}
	

	
	//if the savings account goes below some threshold then we sell our assest value and add the money to savings
	if(my_saving.getValue()<my_saving.min_balance()) {
		
		//first check the assets we have in savings account
		
		if (my_saving.get_AssetValue()>=(my_saving.min_balance() - my_saving.getValue() )) { 
			
			my_saving.set_AssetValue(my_saving.get_AssetValue() - (my_saving.min_balance() - my_saving.getValue() ));
			
			the_events.add(my_saving.deposit((my_saving.min_balance() - my_saving.getValue()), the_time+my_saving.delay_in_return()));
			
		}
		
		else if(my_shortterm.getaccumulatedValue()>= (my_saving.min_balance() - my_saving.getValue() )) {
			the_events_investments.add(my_shortterm.withdraw(-(my_saving.min_balance() - my_saving.getValue()), the_time));
			
			the_events.add(my_saving.deposit((my_saving.min_balance() - my_saving.getValue()), the_time+my_shortterm.delay_in_return()));
			}
		
		else if(my_longterm.getaccumulatedValue()>= (my_saving.min_balance() - my_saving.getValue() )) {
			the_events_investments.add(my_longterm.withdraw(-(my_saving.min_balance() - my_saving.getValue()), the_time));
			
			the_events.add(my_saving.deposit((my_saving.min_balance() - my_saving.getValue()), the_time+my_longterm.delay_in_return()));
			}
		
		
		
	}
	
	
	the_events.addAll(the_events_investments);
	
	return the_events;
	
		}
	
	
private long totalTo(final Collection<Event> the_events)
{
	long total = 0;
	for (Event e : the_events)
		{total += e.value;}
	return total;
}
	
	
	
	
}
